home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / tjgold.zip / INSTALL.004 / FGUSER17.TXT < prev    next >
Text File  |  1995-05-29  |  29KB  |  685 lines

  1.                         Creating & Managing Databases
  2.  
  3.                                      "This meane and unrefined stuffe of
  4.                                       mine will make your glistering
  5.                                       gold but more to shine"
  6.                                              Anne Bradstreet, 1612-1672
  7.  
  8. Introduction
  9.  
  10.           The GOLDDB unit provides a complete set of routines for
  11.      developing database applications such as a customer list or parts
  12.      inventory. Developers of database toolkits often complicate the
  13.      final product by offering several levels of access to database
  14.      information. The simplest level doesn't allow enough flexibility
  15.      while the deepest level becomes so complicated that a complete
  16.      understanding of database management and indexing is required.
  17.      Keeping the developer in mind, we have attempted to deliver real
  18.      flexibility while making the GOLDDB unit as simple as possible.
  19.  
  20. File Support
  21.  
  22.           The GOLDDB unit supports the extremely popular dBase III+ file
  23.      format (dBase is a trademark of Borland International). Only one
  24.      index file per database is permitted, and the index file name uses
  25.      the associated database's file name while appending our own .GDX
  26.      (Gold Database Index) extension. For example, if the database was
  27.      named PARTS.DBF, the index would be named PARTS.GDX. Behind the
  28.      scenes, Gold uses a custom implementation of Btree indexing.
  29.  
  30.           GOLDDB also supports the standard .DBT memo file.
  31.  
  32. General Database Activities
  33.  
  34.      Following are the general routines that relate to the general database access.
  35.  
  36.      DBFExist(FN: PathStr): boolean;
  37.  
  38.      Determines whether or not a database file exists. Sometimes the user may not provide the .DBF extension, so DBFExist forces this extension before making its determination. To ensure that the application flows smoothly as files are opened, it is recommended that you check for their existence first.
  39.  
  40.      The following code sample demonstrates checking for the existence of the data file.
  41.  
  42.           begin { main }
  43.              if DBFExist('DEMCUST') then
  44.              begin
  45.                 Handle := DbOpenDataSet('DEMCUST.DBF');
  46.                 if (Handle = 0) then
  47.                    PromptOK(' DATA ERROR ','Unable to open DEMCUST.DBF
  48.                                          or one of its related files.')
  49.                 else
  50.                    { Data activity takes place here }
  51.                 if Handle > 0 then
  52.                    DbCloseDatabase(Handle);
  53.              end;
  54.              Clear(LightGrayOnBlack,' ');
  55.           end.
  56.  
  57.           The above code illustrates the use of the database handle.
  58.      Since Gold allows you to open multiple databases at any one time,
  59.      you need some way of informing Gold which database you want to work
  60.      with. When a database is opened, Gold returns a handle. The
  61.      procedure DbSetActiveDatabase is used to set the focus to a
  62.      specific database, by passing a specific handle. All database
  63.      operations are directed to the database with focus. Notice that
  64.      this same handle is used in the call to DbCloseDatabase. These
  65.      primary database arrangement functions are defined as follows:
  66.  
  67.      DbOpenDataSet(DBFile: pathstr): integer;
  68.  
  69.           Opens, validates and assigns a handle to the specified
  70.      database. If it exists, the associated index file is also opened
  71.      and validated. The integer value that is returned becomes the
  72.      handle that identifies the database just opened, i.e. the database
  73.      with focus. A returned handle value of zero implies that the data
  74.      file did not validate correctly and may be corrupt.
  75.  
  76.           GOLDDB maintains an internal list of pointers, each of which
  77.      individually points to the associated attributes of the opened data
  78.      files. The file handle is actually the value of the associated
  79.      sequential entry within this list.
  80.  
  81.      DbSetActiveDataBase(Handle:integer);
  82.  
  83.           If more than one database is opened at a time, focus may be
  84.      changed to another file by specifying its assigned handle. All
  85.      subsequent activity associated with a database is focused on the
  86.      new file handle until focus is changed again or the file is closed.
  87.  
  88.      DbCloseDataBase(Handle: integer);
  89.  
  90.           After all activity has been completed surrounding the data, a
  91.      database must be closed to free up the memory that was allocated
  92.      for its use. The handle identifies the database that will be
  93.      closed.
  94.  
  95.      Listed below are some other common data management routines.
  96.  
  97.      DbSetFullStrings(On: boolean);
  98.  
  99.           Inside a dBase file, all data is stored as "space padded"
  100.      strings. This procedure instructs Gold on how to return data from
  101.      each field. Setting the parameter to FALSE will strip all the
  102.      trailing spaces from the data before it is returned to the
  103.      application. The default is TRUE, so that the complete length of
  104.      the field is returned each time.
  105.  
  106.      DbIndexedField: integer;
  107.  
  108.           Returns the field used for the database index. A value of zero
  109.      implies that the index file is not valid or does not exist.
  110.  
  111.      DbSeqSearch(var RecNo: longint; FieldNo: integer;
  112.                                            SearchTxt: String): boolean;
  113.  
  114.           Instructs Gold to perform a sequential search fo the database,
  115.      i.e. a non-indexed search which checks the field in natural or
  116.      stored order. A database index is not used for this search, even if
  117.      one exists. Passing a value of zero to RecNo signals the search to
  118.      begin at record one, any other value begins at the specified
  119.      record.
  120.  
  121.      DbCloseAllDatabases;
  122.  
  123.           If more than one database has been opened to perhaps compare
  124.      data or design some relational report about the data, all opened
  125.      databases may be closed by calling this one procedure. This is in
  126.      lieu of running down the list of opened data files and closing them
  127.      one at a time.
  128.  
  129. What's the Header?
  130.  
  131.           Each .DBF file contains certain information which defines the
  132.      database characteristics along with the fields it contains. This
  133.      data is stored at the beginning of the DBS file and is referred to
  134.      as the header. The first 32 bytes of the header is information
  135.      which specifically pertains to the .DBF file, e.g. version number,
  136.      last data it was modified, etc. There is an additional 32 bytes
  137.      added to the header for each field within the database.
  138.  
  139.           The GOLDDB unit maintains a record depicting the first 32
  140.      bytes of the header and is defined as follows:
  141.  
  142.           HeaderInfo = record
  143.              VersionNumber: byte;
  144.              Update: array [1..3] of byte;
  145.              NbrRec: longint;
  146.              HdrLen: integer;
  147.              RecLen: integer;
  148.              Reserved: array [1..20] of char;
  149.           end;
  150.  
  151.           You do not need to access this record directly. Use the
  152.      following list of routines to retrieve this information.
  153.  
  154.      DbGetVersion: byte;
  155.  
  156.           Returns the version byte of the database file. This is
  157.      generally one of two values, either a 3 ($03) or a 131 ($83). A
  158.      value of 131 ($83) indicates that at least one memo field exists in
  159.      the database. Some third party dBase-clone vendors have decided to
  160.      use this version byte as their finger print, modifying it to their
  161.      own value. When a database is opened Gold  inspects the version
  162.      byte to ensure that GOLDDB is using a true dBase III+ compatible
  163.      file.
  164.  
  165.      DbGetUpDate: dates;
  166.  
  167.           Another part of the header is a date which represents the last
  168.      time a value was changed in the database. This function returns a
  169.      longint value of type dates, that may be converted to a string
  170.      value using JultoStr.
  171.  
  172.      DbTotalFields: integer;
  173.  
  174.      Represents the total number of fields defined in the database.
  175.  
  176.      DbGetNumRecs: longint;
  177.  
  178.           Each time a record is added to the data file, this value is
  179.      incremented by one. It represents all records whether or not they
  180.      have been marked as deleted.
  181.  
  182.      DbGetHdrLen: integer;
  183.  
  184.           The header length is made up of a multiple of 32 byte sections
  185.      and is terminated with a single <CR> ($0D) character. The first 32
  186.      byte section contains the file specific information while the
  187.      remaining sections are field definitions. The header length is
  188.      inclusive of the end-of-header character.
  189.  
  190.      DbGetRecLen: word;
  191.  
  192.           The first byte of each record is the status byte. The record
  193.      length is defined as all the individual field lengths added
  194.      together plus one byte (status byte).
  195.  
  196.      DbCurrRecNum: longint;
  197.  
  198.           The current record is the record being held in the work space,
  199.      i.e. the location of the database cursor. GOLDDB unit maintains a
  200.      small portion of memory which is the exact size of a record from
  201.      the associated database.
  202.  
  203. Field Specifics
  204.  
  205.           Records in a DBF file are said to be of fixed length. This
  206.      means that each record is exactly the same length, regardless of
  207.      the data stored within. Each record is made up of a pre-defined set
  208.      of fields. Each field has its own definition which resides in the
  209.      database header. The GOLDDB unit maintains a record type which is
  210.      defined as follows:
  211.  
  212.           FieldDesc = record
  213.              FdName: array [1..11] of char;
  214.              FdType: char;
  215.              Reserved1: array [1..4] of char;
  216.              FdLength: byte;
  217.              FdDec: byte;
  218.              Reserved2: array [1..14] of char;
  219.           end;
  220.  
  221.           You do not need to access this record directly. Use the
  222.      following list of routines to retrieve this information.
  223.  
  224.      DbGetFldName(FieldNo: integer): string;
  225.  
  226.           Each field has its own name. The name may be no longer than 10
  227.      characters and must begin with an alpha character. The remaining
  228.      characters may be alphanumeric or the underscore character.
  229.  
  230.      DbGetFldType(FieldNo: integer): char;
  231.  
  232.      GOLDDB supports only dBase III+ compatible field types as follows:
  233.  
  234.           C - Character
  235.           N - Numeric (includes floating)
  236.           L - Logical
  237.           D - Date
  238.           M - Memo
  239.  
  240.      DbGetFldLength(FieldNo: integer): integer;
  241.  
  242.           Each field type has its own limitations. The supported field
  243.      types have the following field length definitions:
  244.  
  245.           C - 1 to 254 characters
  246.           N - 1 to 19 characters
  247.           L - 1 character ( T or F )
  248.           D - 8 characters
  249.           M - 10 characters
  250.  
  251.      DbGetFldDec(FieldNo: integer): integer;
  252.  
  253.           When a field is defined as a numeric type it may also have a
  254.      number of decimal places. This value may not be greater than [(the
  255.      defined field length) - 2] and may never be greater than 9.
  256.  
  257. Retrieving Field Information
  258.  
  259.           Behind the scenes, all data in a .DBF file is stored in
  260.      character form. Each of the following routines performs an
  261.      appropriate conversion and returns the data in its native form. Any
  262.      time information is requested about a specific field the whole
  263.      record is loaded into the internal work space. This is so that
  264.      subsequent requests from the same record will not have to be read
  265.      from the storage media.
  266.  
  267.           The following code fragment demonstrates the ease of
  268.      retrieving data from a database file:
  269.  
  270.           procedure DatabaseToScreen(RecNo:longint);
  271.           {}
  272.           begin
  273.              with UserRec do
  274.              begin
  275.                 Entered := DbGetFldDate(RecNo,1);
  276.                 Client := DbGetFldString(RecNo,2);
  277.                 Addr1 := DbGetFldString(RecNo,3);
  278.                 Addr2 := DbGetFldString(RecNo,4);
  279.                 City := DbGetFldString(RecNo,5);
  280.                 State := DbGetFldString(RecNo,6);
  281.                 Zip := DbGetFldString(RecNo,7);
  282.                 Country := DbGetFldString(RecNo,8);
  283.                 Phone := DbGetFldString(RecNo,9);
  284.                 Units := DbGetFldLong(RecNo,10);
  285.                 DbGetFldMemo(RecNo,11,MemoFldVar);
  286.              end;
  287.           end; { DatabaseToScreen }
  288.  
  289.      DbGetFldString(RecNo: longint; FieldNo: integer): string;
  290.  
  291.           Since all data stored in a .DBF file is in character form,
  292.      there is no validation performed for the calling field. This
  293.      routine may be called using any field, but you may have to do your
  294.      own type conversion for field types other than character. It is
  295.      recommended that you use the following routines when calling field
  296.      types other than character.
  297.  
  298.      DbGetFldInt(RecNo: longint; FieldNo: integer): integer;
  299.  
  300.           Returns an integer value of the string stored in the database
  301.      field. A validation is performed first to ensure that the field
  302.      being requested is numeric.
  303.  
  304.      DbGetFldLong(RecNo: longint; FieldNo: integer): longint;
  305.  
  306.           Returns a longint value of the string stored in the database
  307.      field. A validation is performed first to ensure that the field
  308.      being requested is numeric.
  309.  
  310.      DbGetFldReal(RecNo: longint; FieldNo: integer): extended;
  311.  
  312.           Returns a real value of the string stored in the database
  313.      field. A validation is performed first to ensure that the field
  314.      being requested is numeric.
  315.  
  316.      DbGetFldLogical(RecNo: longint; FieldNo: integer): boolean;
  317.  
  318.           Validates that the field is a logical field, and returns a
  319.      TRUE or FALSE value. Note that Gold (line dBase) stores a "T" or
  320.      "F" in the field.
  321.  
  322.      DbGetFldDate(RecNo: longint; FieldNo: integer): Dates;
  323.  
  324.           Validates that the field is a date field, AND returns the
  325.      Julian date. Refer to Chapter 18 for a description of Gold data
  326.      management routines which can convert Julian dates to strings, etc.
  327.  
  328.      DbGetFldMemo(RecNo: longint; FieldNo: integer;var
  329.  
  330.      MemoDetails:MemoCfg);
  331.  
  332.           Ensures that the field is a memo field and that a memo is
  333.      actually stored for this record. If these requirements are met,
  334.      this routine populates the MemoDetails variable with the data
  335.      stored in the associated .DBT file.
  336.  
  337.      DbGetMemoRecNum(RecNo:longint;FieldNo:integer):longint;
  338.  
  339.           Provides a means to extract the numeric value stored in the
  340.      memo field of the .DBF file. This number (of ten digits, or less)
  341.      indicates the record number, in the memo file, of the first part of
  342.      the memo text. A zero is returned when there is no memo data for
  343.      the record specified.
  344.  
  345.      Note:
  346.  
  347.           Memo files are built from 512 byte blocks of data. The first
  348.      block, block 0, is the header of the file and stores only the value
  349.      of the next available block. The remaining blocks, 1 thru N,
  350.      directly equate to the 10 digit value stored in the memo field.
  351.  
  352.      DbFldIsEmpty(RecNo: longint;FieldNo: integer):boolean;
  353.  
  354.           Returns TRUE if the field in question only contains spaces,
  355.      i.e. is empty. (Remember that dBase fields are always padded with
  356.      spaces to fill the field).
  357.  
  358.           A Gold error is raised if you try to get data of the wrong
  359.      type, e.g. you try to call DbGetFldReal for a logical field. Be
  360.      sure to use LastDbError to check the error status after calling a
  361.      dbGetFldxxx function. Better still, verify the field using
  362.      DbGetFldType (discussed earlier) prior to calling DbGetFldxxx
  363.      function..
  364.  
  365. Updating Field Information
  366.  
  367.           A variety of functions (all named DbSetFldxxx) are used to add
  368.      new records, or update existing records. For example, the function
  369.      DbSetFldDate (shown in the code fragment below) sets a new value
  370.      for a date field. It is important that you understand that these
  371.      functions do not directly access the data on disk. Gold maintains
  372.      all the information about the active record (i.e. the record
  373.      containing the database cursor) in a special buffer called the work
  374.      space. The set and get functions all access the workspace, not the
  375.      physical on-disk record.
  376.  
  377.           Having used the set functions to update the workspace, you
  378.      must call DbAddRecord or DbPutRecord to transfer the record from
  379.      the workspace to disk.
  380.  
  381.           Memo fields are handled slightly differently. The memo routine
  382.      updates a separate file and then the memo field (in the DBF file)
  383.      is updated with the correct memo block number.
  384.  
  385.      The following code fragment illustrates this technique.
  386.  
  387.           procedure ScreenToDatabase;
  388.           {}
  389.           var MemRecNum: longint;
  390.           begin
  391.              with UserRec do
  392.              begin
  393.                 DbSetFldDate(1,Entered);
  394.                 DbSetFldString(2,Client);
  395.                 DbSetFldString(3,Addr1);
  396.                 DbSetFldString(4,Addr2);
  397.                 DbSetFldString(5,City);
  398.                 DbSetFldString(6,State);
  399.                 DbSetFldString(7,Zip);
  400.                 DbSetFldString(8,Country);
  401.                 DbSetFldString(9,Phone);
  402.                 DbSetFldInt(10,Units);
  403.                 MemRecNum := DbSetFldMemo(11,Comments);
  404.              end;
  405.              if Adding then
  406.              begin
  407.                 DbAddRecord;
  408.                 Adding := false;
  409.              end
  410.              else
  411.                 DbPutRecord;
  412.           end; { ScreenToRecord }
  413.  
  414.           Listed below are the individual procedures used to modify
  415.      individual fields in the work space:
  416.  
  417.      DbSetFldString(FieldNo: integer; StrVar: string);
  418.  
  419.           After validating the field type, this routine updates the work
  420.      space with the passed string value.
  421.  
  422.      DbSetFldInt(FieldNo: integer; IntVar: longint);
  423.  
  424.           After validating the field type, this routine updates the work
  425.      space with the passed numeric value.
  426.  
  427.      DbSetFldReal(FieldNo: integer; RealVar: Extended);
  428.  
  429.           After validating the field type, this routine updates the work
  430.      space with the passed real value.
  431.  
  432.      DbSetFldLogical(FieldNo: integer; BoolVar: boolean);
  433.  
  434.           After validating the field type, this routine updates the work
  435.      space with a T or an F based on the value passed in BoolVar.
  436.  
  437.      DbSetFldDate(FieldNo: integer; DateVar: longint);
  438.  
  439.           After validating the field type, this routine converts the
  440.      passed Julian date to the format YYYYMMDD and updates the work
  441.      space.
  442.  
  443.      DbSetFldMemo(FldNo: integer;var SL: SingleLL): longint;
  444.  
  445.           Updates the .DBT file with the information contained in the
  446.      single linked list after which it sets the appropriate field with
  447.      the newly updated block number of the .DBT file.
  448.  
  449. Record Specific Routines
  450.  
  451.           Some of the routines in GOLDDB deal specifically with the
  452.      whole record. A record is a set of data inclusive of all the fields
  453.      defined in the header, with one byte added for the record's status.
  454.  
  455.      DbRecordIsActive(RecNo: longint): boolean;
  456.  
  457.      This function returns false if the record has been deleted.
  458.  
  459.           This routine loads the entire record into the work space and
  460.      reads the status byte. It will be a space character if the record
  461.      is active or an asterisk (*) character if the record has been
  462.      marked as deleted.
  463.  
  464.      DbAddRecord;
  465.  
  466.           This procedure should only be called after all data changes to
  467.      a record have been completed. The data currently in the work space
  468.      is appended to the end of the .DBF file.
  469.  
  470.      DbPutRecord;
  471.  
  472.           This procedure should only be called after all modifications
  473.      to a record have been completed. The data currently in the work
  474.      space is returned to the record from which it was retrieved.
  475.  
  476.      DbDeleteRecord(RecNo: longint);
  477.  
  478.           Updates the status byte of the specified record with an
  479.      asterisk (*) character. It is now marked as deleted although the
  480.      data is still accessible.
  481.  
  482.      DbUnDeleteRecord(RecNo: longint);
  483.  
  484.           Marks a record as undeleted or active. A space character is
  485.      placed into the status byte.
  486.  
  487. Creating a New DBF File
  488.  
  489.           Creating a new data file is simple. It is helpful (if not
  490.      essential!) to first determine what data will be stored in the
  491.      database and which field types best accommodate this data. Call
  492.      DbAddDbfField once for each field to be included in the database,
  493.      then call DbBuildDataFile. These functions are defined as follows:
  494.  
  495.      DbAddDbfField(FldName: string; FldType: char; FldLen, FldDecPl: integer): integer;
  496.  
  497.           Adds the passed information to a temporary internal list which
  498.      is used later to build the new database. Returns a zero value if
  499.      the operation was successful.
  500.  
  501.           Behind the scenes, Gold verifies all the data to ensure it
  502.      remains compatible with the dBase III+ format. See field specifics
  503.      for details on field requirements.
  504.  
  505.      DbBuildDataFile( FN: Pathstr; NDXFld : byte): integer;
  506.  
  507.           After all fields have been added using DbAddDbfField, this
  508.      routine must be called once to create the new data file. You may
  509.      specify the field from which to build the index. If a zero is
  510.      passed, no index file is built. If a memo field is included in the
  511.      list of fields, a memo file with the same name will automatically
  512.      be included. Returns a zero value if the file was created
  513.      successfully.
  514.  
  515.      Here's an example:
  516.  
  517.           procedure CreateNewDataFile;
  518.           {}
  519.           var EValue: integer;
  520.           begin
  521.              EValue := 0;
  522.              inc(EValue,DbAddDbfField('DATE','D',8,0));
  523.              inc(EValue,DbAddDbfField('CLIENT','C',30,0));
  524.              inc(EValue,DbAddDbfField('ADDR1','C',30,0));
  525.              inc(EValue,DbAddDbfField('ADDR2','C',30,0));
  526.              inc(EValue,DbAddDbfField('CITY','C',22,0));
  527.              inc(EValue,DbAddDbfField('STATE','C',2,0));
  528.              inc(EValue,DbAddDbfField('ZIP','C',10,0));
  529.              inc(EValue,DbAddDbfField('COUNTRY','C',20,0));
  530.              inc(EValue,DbAddDbfField('PHONE','C',10,0));
  531.              inc(EValue,DbAddDbfField('UNITS','N',10,0));
  532.              if EValue = 0 then
  533.                 inc(EValue,DbBuildDataFile(FN,1))
  534.              if EValue <> 0 then
  535.              begin
  536.                PromptOK(' File Error ','Unable to create file!');
  537.                Halt;
  538.              end;
  539.           end; { CreateNewDataFile }
  540.  
  541.           The code illustrates a convenient way to trap for errors
  542.      without bogging the code in nested if statements. EValue will be
  543.      incremented by zero each time a field is added successfully. If
  544.      DbAddDbfField fails, a non-zero value will be returned. EValue is
  545.      then checked before building the data file to ensure that all
  546.      fields were added correctly.
  547.  
  548. Powerful Searching and Sorting
  549.  
  550.           The power of a database lies not in its ability to store
  551.      information, but how quickly and in what order this information can
  552.      be retrieved. This power is achieved by indexing, and the following
  553.      index functions are available in Gold:
  554.  
  555.      NdxBuildNew(FieldNo: integer): integer;
  556.  
  557.           Builds a brand new index file. Remember that the index file
  558.      retains the same name as the associated data file. This routine
  559.      will allow the application to switch the field on which the index
  560.      file is built.
  561.  
  562.      SetShowNdxProgress(Proc: ShowNdxProgressProc);
  563.  
  564.           Turns on a hook that will be called each time a key is added
  565.      to the new index file. Used in conjunction with WriteProgressLong
  566.      to display the progress of the index build. Proc must be declared
  567.      at the root level and be declared as a far procedure. The current
  568.      record number and total number of records are passed each time the
  569.      hook is called.
  570.  
  571.      NdxGetRecNum(EntryNum: longInt) : longInt;
  572.  
  573.      Returns the record number of a specific entry in the index.
  574.  
  575.      NdxCount : longint;
  576.  
  577.           Returns the total number of entries in the index. This should
  578.      be the same as the total number of active records in the data file.
  579.  
  580.      NdxGotoFirst: longint;
  581.  
  582.      Returns the record number of the first entry of the index.
  583.  
  584.      NdxGotoLast: longint;
  585.  
  586.      Returns the record number of the last entry in the index.
  587.  
  588.      NdxGotoNext: longint;
  589.  
  590.           Returns the record number of the next index entry from your
  591.      present location.
  592.  
  593.      NdxGotoPrev: longint;
  594.  
  595.           Returns the record number of the previous index entry from
  596.      your present location.
  597.  
  598.      DbFindFirst(FieldNo: integer; var findValue;
  599.                                        PartialMatch: boolean): longint;
  600.  
  601.           Returns the record number of the first match successfully
  602.      found. When PartialMatch is set to true, the user may search for
  603.      incomplete information.
  604.  
  605.      DbFindNext: longInt;
  606.  
  607.           Returns the record number of the next match found with the
  608.      same criteria used in DbFindFirst. Always call DbFindFirst prior to
  609.      the first call to DbFindNext.
  610.  
  611.      NdxSetMaxPages(n: Word);
  612.  
  613.           Sets the number of pages that can be loaded into memory at
  614.      once. The default is 25 pages. The default will suit the majority
  615.      of applications, but you may increase or decrease this value as
  616.      necessary. Increasing allows more of the data to remain in memory
  617.      and reduces the number of disk reads, and at the same time reduces
  618.      the amount of memory available for your program. Decreasing does
  619.      just the opposite, reducing the amount of data in memory, but
  620.      increasing the number of disk reads.
  621.  
  622.      NdxSetUpperCase(x: boolean);
  623.  
  624.           Pass TRUE to force the index to be built in uppercase. This is
  625.      the default.
  626.  
  627.      NdxSetMaxStrLength(n: Byte);
  628.  
  629.           Sets the maximum length that will be accepted into an index
  630.      key. The default is 30 characters. Increasing this value will also
  631.      increase the size of the index. If you change the index string
  632.      length, you must rebuild the index.
  633.  
  634. Maintenance Procedures
  635.  
  636.           A DBF file must remain synchronized with its associated index
  637.      (.GDX) and memo (.DBT) files. Data can be currupted for a variety
  638.      of reasons, e.g. disk failures, coding bugs (yours, not ours!). If
  639.      the data gets corrupted, you can use one of the following routines
  640.      to fix the problem:
  641.  
  642.      DbRebuildMemo(FName: PathStr): integer;
  643.  
  644.           Any time a memo is added or modified in any way (even if only
  645.      one character is changed)  the entire memo is appended to the same
  646.      memo file. The space where the memo existed is never modified. The
  647.      database memo field is updated to reflect the new memo block
  648.      number. This mechansim is fast, but tends to waste huge amounts of
  649.      space since the old memo data is never removed during normal
  650.      operation. Calling this routine removes all unused blocks and
  651.      updates the memo fields in the datafile as the new memo file is
  652.      written.
  653.  
  654.      NdxRebuild: integer;
  655.  
  656.           If an index file becomes unsynchronized with its associated
  657.      data file, it will become necessary to rebuild it to resynchronize
  658.      the files. NdxRebuild uses the current index field as its key. The
  659.      old index file is overwritten by the new one.
  660.  
  661.           When a database record is deleted, the record is marked as
  662.      deleted, but remains stored in the database. This mechansim makes
  663.      record undeletion possible. Use the following function when you
  664.      want to physically remove all deleted records from a DBF file:
  665.  
  666.      DbPackFile(FName: PathStr; IndexField: integer): integer;
  667.  
  668.           Removes all records that are currently marked as deleted. Also
  669.      rebuilds the associated index using the current index field.
  670.      Remember that they must remain synchronized.
  671.  
  672. Managing Database Colors
  673.  
  674.           Database colors are actually quite simple to deal with. There
  675.      are none!
  676.  
  677. Error Recovery
  678.  
  679.           One quality which separates the professional from the novice
  680.      is the ability to gracefully recover from an error. GOLDDB contains
  681.      a wealth of  internal error checking. If you call a routine which
  682.      has the potential to fail, call the function LastDbError to make
  683.      sure the operation was successful.
  684.  
  685.